<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>凹语言版 - NES 模拟器</title>
  <link href="./style.css" rel="stylesheet">
</head>
<body>
  <div class="game">
    <div class="title">Wa Game <sup><em>2023</em></sup></div>
    <div class="game-box">
      <div class="joy-left">
        <div class="bumper-left"></div>
        <div id="Select" class="select-btn"></div>
        <div id="Start" class="start-btn"></div>
        <div id="Reset" class="reset-btn"></div>
        <div class="analog"></div>
      </div>
      <div class="joy-right">
        <div class="game-name">Game Name</div>
        <select class="game-select">
          <option value="0">坦克大战</option>
          <option value="1">超级玛丽</option>
          <option value="2">公路赛车</option>
          <option value="3">魂斗罗</option>
        </select>
        <div class="bumper-right"></div>
        <div class="dpad-container">
          <div id="X" class="dpad-x"></div>
          <div id="A" class="dpad-a"></div>
          <div id="B" class="dpad-b"></div>
          <div id="Y" class="dpad-y"></div>
        </div>
      </div>
      <div class="screen-outer">
        <div class="screen-inner"></div>
        <canvas id="nes" width="256" height="240"></canvas>
      </div>
    </div>
    <div class="hint">
      方向键：<em>小键盘方向键</em>
      Start：<em>回车</em>
      Select：<em>空格</em>
      A：<em>Ctrl</em>
      B：<em>Shift</em>
      Reset：<em>R</em>
    </div>
  </div>
<script type="text/javascript" src="./nes.js"></script>
<script src="./hammer.js"></script>
<script src="./my-joystick.js"></script>
<script>
  const IS_MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  if (IS_MOBILE) {
    const gameDom = document.querySelector('.game');
    gameDom.style.transform = 'rotate(90deg) translate(0, -43%) scale(0.8)';
    gameDom.style.transformOrigin = 'left top';
    const hintDom = document.querySelector('.hint')
    hintDom.style.display = 'none'
  }

  let app = new WaApp();

  let key_map = new Map();

  let lastDownTarget, nesCanvas;
  let lastKeyTimeStamp;

  let btnA = false;
  let btnB = false;
  let btnSelect = false;
  let btnStart = false;
  let btnUp = false;
  let btnDown = false;
  let btnLeft = false;
  let btnRight = false;
  let btnReset = false;

  function press_key(key) {
    if (key_map.has(key)) {
      let k = key_map.get(key);
      k.pressed = true;
    }
    else {
      const k = {}
      k.pressed = true;
      key_map.set(key, k);
    }
  }

  function release_key(key) {
    if (key_map.has(key)) {
      const k = key_map.get(key);
      k.pressed = false;
    }
  }

  function get_key_status(key) {
    if (key_map.has(key)) {
      const k = key_map.get(key);
      return k.pressed;
    }
    return false;
  }

  let jsconf = {
    frontColor: "radial-gradient(circle at top, #788084 0%,#212427 100%)",
    backColor: "linear-gradient(to top, #525659 40%, #424040 100%)",
    backR: 100,
    frontR: 40,
    distanceX: null,
    distanceY: null,
  };
  const joystick = new MyJoystick(jsconf, IS_MOBILE);
  joystick.openJoystick(function (ev) {
    release_key('Up')
    release_key('Down')
    release_key('Left')
    release_key('Right')

    if (ev.direction === 'up') {
      press_key('Up');
    } else if (ev.direction === 'down') {
      press_key('Down');
    } else if (ev.direction === 'left') {
      press_key('Left');
    } else if (ev.direction === 'right') {
      press_key('Right');
    } else if (ev.direction === 'left-up') {
      press_key('Left');
      press_key('Up')
    } else if (ev.direction === 'right-up') {
      press_key('Right');
      press_key('Up');
    } else if (ev.direction === 'left-down') {
      press_key('Left');
      press_key('Down');
    } else if (ev.direction === 'right-down') {
      press_key('Right');
      press_key('Down');
    }
  });

  // 更新游戏
  const gameSelectDom = document.querySelector('.game-select');
  gameSelectDom.addEventListener('change', function (ev) {
    const value = ev.target.value;
    app.NES_InitGame(parseInt(value));
  });

  {
    let A = document.getElementById("A");
    A.addEventListener("touchstart", function(ev){
      press_key('A')
    }, false);
    A.addEventListener("touchend", function(ev){
      release_key('A')
    }, false);
  }
  {
    let B = document.getElementById("B");
    B.addEventListener("touchstart", function(ev){
      press_key('B')
    }, false);
    B.addEventListener("touchend", function(ev){
      release_key('B')
    }, false);
  }
  {
    let X = document.getElementById("X");
    X.addEventListener("touchstart", function(ev){
      press_key('X')
    }, false);
    X.addEventListener("touchend", function(ev){
      release_key('X')
    }, false);
  }
  {
    let Y = document.getElementById("Y");
    Y.addEventListener("touchstart", function(ev){
      press_key('Y')
    }, false);
    Y.addEventListener("touchend", function(ev){
      release_key('Y')
    }, false);
  }
  {
    let Select = document.getElementById("Select");
    Select.addEventListener("touchstart", function(ev){
      press_key('Select')
    }, false);
    Select.addEventListener("touchend", function(ev){
      release_key('Select')
    }, false);
  }
  {
    let Start = document.getElementById("Start");
    Start.addEventListener("touchstart", function(ev){
      press_key('Start')
    }, false);
    Start.addEventListener("touchend", function(ev){
      release_key('Start')
    }, false);
  }
  {
    let Reset = document.getElementById("Reset");
    Reset.addEventListener("touchstart", function(ev){
      press_key('Reset')
    }, false);
    Reset.addEventListener("touchend", function(ev){
      release_key('Reset')
    }, false);
  }

  window.onload = () => {
    document.addEventListener('keydown', (event) => {
      switch (event.key) {
        case 'Control':
          press_key('A');
          break;

        case 'Shift':
          press_key('B');
          break;

        case ' ':
          press_key('Select')
          break;

        case 'Enter':
          press_key('Start')
          break;

        case 'ArrowUp':
          press_key('Up')
          break;

        case 'ArrowDown':
          press_key('Down')
          break;

        case 'ArrowLeft':
          press_key('Left')
          break;

        case 'ArrowRight':
          press_key('Right')
          break;

        case 'r':
          press_key('Reset')
          break;
      }
    }, false);

    document.addEventListener('keyup', (event) => {
      switch (event.key) {
        case 'Control':
          release_key('A');
          break;

        case 'Shift':
          release_key('B');
          break;

        case ' ':
          release_key('Select');
          break;

        case 'Enter':
          release_key('Start')
          break;

        case 'ArrowUp':
          release_key('Up')
          break;

        case 'ArrowDown':
          release_key('Down')
          break;

        case 'ArrowLeft':
          release_key('Left')
          break;

        case 'ArrowRight':
          release_key('Right')
          break;

        case 'r':
          release_key('Reset')
          break;
      }
    }, false);

    app.init().then((result) => {
      app.main();

      app.NES_InitGame(0);

      let preTimeStamp;
      let stepAnima = function (timeStamp) {
        // 执行
        if (get_key_status('X')){
          btnA = !btnA
        } else {
          btnA = get_key_status('A');
        }
        if (get_key_status('Y')){
          btnB = !btnB
        } else {
          btnB = get_key_status('B');
        }
        btnSelect = get_key_status('Select');
        btnStart = get_key_status('Start');
        btnUp = get_key_status('Up')
        btnDown = get_key_status('Down')
        btnLeft = get_key_status('Left')
        btnRight = get_key_status('Right')
        btnReset = get_key_status('Reset')

        if (btnReset) {
          btnReset = false;
          app.NES_Reset();
        }

        app.NES_SetButtons1(btnA, btnB, btnSelect, btnStart, btnUp, btnDown, btnLeft, btnRight);
        app.NES_StepFrame();

        preTimeStamp = timeStamp;
        window.requestAnimationFrame(stepAnima);
      }
      window.requestAnimationFrame(stepAnima);
    });
  }
</script>
</body>
</html>


